﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Core.Objects;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.ModelConfiguration;
using System.Data.Entity.ModelConfiguration.Configuration;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace System.Data
{
    public class GenericDbContext : DbContext, IDbContext
    {
        public string ConnectionString { get; private set; }
        public GenericDbContext()
            : this("Data Source=121.199.46.107,14333;Initial Catalog=BCard;Integrated Security=False;Persist Security Info=True;User ID=sa;Password=3ghyd123456,.~;MultipleActiveResultSets=True;Connect Timeout=10000;Max Pool Size=5;Application Name=u101")
        {
        }
        public GenericDbContext(string nameOrConnectionString, DbConnection connection)
            : base(connection, true)
        {
            ConnectionString = nameOrConnectionString;
        }

        public GenericDbContext(string nameOrConnectionString)
            : base(nameOrConnectionString)
        {
            ConnectionString = nameOrConnectionString;
        }

        public ObjectContext ObjectContext
        {
            get { return ((IObjectContextAdapter)this).ObjectContext; }
        }

        public override int SaveChanges()
        {
            return base.SaveChanges();
        }

        Database IDbContext.Database
        {
            get { return base.Database; }
        }

        IDbSet<TEntity> IDbContext.Set<TEntity>()
        {
            return base.Set<TEntity>();
        }

        public override Task<int> SaveChangesAsync()
        {
            return base.SaveChangesAsync();
        }

        public override Task<int> SaveChangesAsync(Threading.CancellationToken cancellationToken)
        {
            return base.SaveChangesAsync(cancellationToken);
        }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();//移除复数表名的契约

            //手动装载当前目录下的未加载的dll

            //卸载刚加载的dll

            var typesToRegister = AppDomain.CurrentDomain.GetTypes(x => x.IsPublic && !x.IsAbstract && !String.IsNullOrEmpty(x.Namespace)); 
            Func<Type, bool> predicate = x => x.BaseType != null && x.BaseType.IsGenericType &&
                                              (x.BaseType.GetGenericTypeDefinition() == typeof (EntityTypeConfiguration<>) ||
                                               x.BaseType.GetGenericTypeDefinition() == typeof (ComplexTypeConfiguration<>));
            typesToRegister = typesToRegister.Where(predicate);
            typesToRegister = Assembly.LoadFrom(Path.Combine(Utils.GetBinDirectory(), "Usity.dll"))
                                      .GetTypes()
                                      .Where(predicate);
            foreach (var type in typesToRegister)
            {
                dynamic configurationInstance = Activator.CreateInstance(type);
                modelBuilder.Configurations.Add(configurationInstance);
                System.IO.File.AppendAllText("D:\\ABC.txt", type.FullName + Environment.NewLine);
            }
            System.IO.File.AppendAllText("D:\\ABC.txt", Utils.GetBinDirectory()+Environment.NewLine);

            base.OnModelCreating(modelBuilder);

        }
    }
}
